﻿using System;
using System.Collections.Generic;
using System.Linq;
using appDataContracts;

namespace appServices
{
    public class Supplier : appInterfaces.ISupplier
    {
        private Database db = Database.getInstance();

        public List<SerializedCatalog> getSupplierCatalogs(int supplierId)
        {
            var selectCatalogs = db.check(db.getModel().CATALOG.
                Where(cat => cat.SUPPLIERID == supplierId));

            List<SerializedCatalog> listCatalog = new List<SerializedCatalog>();

            foreach (CATALOG catalog in selectCatalogs)
            {
                listCatalog.Add(Library.getSerializedCatalog(catalog));
            }

            return listCatalog;
        }

        public SerializedSupplier supplierLogin(string login, string password)
        {
            try
            {
                SUPPLIER supplier = (SUPPLIER)db.check(db.getModel().SUPPLIER.
                First(sup => sup.SUPPLIERNAME.Equals(login) && sup.SUPPLIERPASSWORD.Equals(password)));

                return Library.getSerializedSupplier(supplier);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                return null;
            }
        }

        public List<SerializedProduct> getSupplierProducts(int supplierId)
        {
            var selectProducts = db.check(db.getModel().PRODUCT.
                Where(prod => prod.SUPPLIERID == supplierId));

            List<SerializedProduct> listProducts = new List<SerializedProduct>();

            foreach (PRODUCT product in selectProducts)
            {
                List<SerializedCatalog> listCatalogs = new List<SerializedCatalog>();

                foreach (CATALOG catalog in product.CATALOG)
                {
                    listCatalogs.Add(Library.getSerializedCatalog(catalog));
                }

                listProducts.Add(Library.getSerializedProduct(product));
            }

            return listProducts;
        }

        public List<SerializedProduct> getCatalogProducts(int catalogId)
        {
            List<SerializedProduct> listProducts = new List<SerializedProduct>();

            try
            {
                CATALOG catalog = (CATALOG)db.check(db.getModel().CATALOG.
                    First(cat => cat.CATALOGID == catalogId));

                foreach (PRODUCT product in catalog.PRODUCT)
                {
                    listProducts.Add(Library.getSerializedProduct(product));
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                return null;
            }

            return listProducts;
        }

        public List<SerializedCatalog> getProductCatalogs(int productId)
        {
            List<SerializedCatalog> listCatalogs = new List<SerializedCatalog>();

            try
            {
                PRODUCT product = (PRODUCT)db.check(db.getModel().PRODUCT.
                    First(prod => prod.PRODUCTID == productId));

                foreach (CATALOG catalog in product.CATALOG)
                {
                    listCatalogs.Add(Library.getSerializedCatalog(catalog));
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                return null;
            }

            return listCatalogs;
        }

        public bool addCatalog(SerializedCatalog catalog)
        {
            try
            {
                CATALOG newCatalog = new CATALOG();

                newCatalog.CATALOGNAME = catalog.CATALOGNAME;
                newCatalog.CATALOGDESCRIPTION = catalog.CATALOGDESCRIPTION;
                newCatalog.SUPPLIERID = catalog.SUPPLIERID;
                newCatalog.CATALOGIMAGE = catalog.CATALOGIMAGE;

                db.getModel().AddToCATALOG(newCatalog);
                db.getModel().SaveChanges();

                return true;
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                return false;
            }
        }

        public bool addProduct(SerializedProduct product, List<int> catalogsId)
        {
            try
            {
                PRODUCT newProduct = new PRODUCT();

                newProduct.PRODUCTNAME = product.PRODUCTNAME;
                newProduct.PRODUCTPRICE = product.PRODUCTPRICE;
                newProduct.PRODUCTDESCRIPTION = product.PRODUCTDESCRIPTION;
                newProduct.PRODUCTIMAGE = product.PRODUCTIMAGE;
                newProduct.SUPPLIERID = product.SUPPLIERID;                

                db.getModel().AddToPRODUCT(newProduct);
                db.getModel().SaveChanges();

                foreach (int id in catalogsId)
                {
                    CATALOG catalog = (CATALOG)db.check(db.getModel().CATALOG.
                        First(cat => cat.CATALOGID == id));

                    catalog.PRODUCT.Add(newProduct);
                    db.getModel().SaveChanges();
                }

                return true;
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);

                return false;
            }
        }

        public bool updateCatalog(SerializedCatalog catalog)
        {
            try
            {
                CATALOG catalogUpdate = (CATALOG)db.check(db.getModel().CATALOG.
                First(cata => cata.CATALOGID == catalog.CATALOGID));

                catalogUpdate.CATALOGNAME = catalog.CATALOGNAME;
                catalogUpdate.CATALOGDESCRIPTION = catalog.CATALOGDESCRIPTION;
                catalogUpdate.SUPPLIERID = catalog.SUPPLIERID;
                catalogUpdate.CATALOGIMAGE = catalog.CATALOGIMAGE;

                db.getModel().SaveChanges();

                return true;
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);

                return false;
            }
        }

        public bool updateProduct(SerializedProduct product, List<int> catalogsId)
        {
            try
            {
                PRODUCT productUpdate = (PRODUCT)db.check(db.getModel().PRODUCT.
                    First(prod => prod.PRODUCTID == product.PRODUCTID));

                productUpdate.PRODUCTNAME = product.PRODUCTNAME;
                productUpdate.PRODUCTPRICE = product.PRODUCTPRICE;
                productUpdate.PRODUCTDESCRIPTION = product.PRODUCTDESCRIPTION;
                productUpdate.PRODUCTIMAGE = product.PRODUCTIMAGE;

                db.getModel().SaveChanges();

                List<CATALOG> catalogs = new List<CATALOG>();

                foreach (CATALOG catalog in productUpdate.CATALOG)
                {
                    catalogs.Add(catalog);
                }

                foreach (CATALOG catalog in catalogs)
                {
                    catalog.PRODUCT.Remove(productUpdate);
                    db.getModel().SaveChanges();
                }

                foreach (int id in catalogsId)
                {
                    CATALOG catalog = (CATALOG)db.check(db.getModel().CATALOG.
                        First(cat => cat.CATALOGID == id));

                    catalog.PRODUCT.Add(productUpdate);
                    db.getModel().SaveChanges();
                }

                return true;
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);

                return false;
            }
        }

        public bool updateSupplier(SerializedSupplier supplier)
        {
            try
            {
                SUPPLIER supplierUpdate = (SUPPLIER)db.check(db.getModel().SUPPLIER.
                    First(sup => sup.SUPPLIERID == supplier.SUPPLIERID));

                supplierUpdate.SUPPLIERADRESS = supplier.SUPPLIERADRESS;
                supplierUpdate.SUPPLIERCITY = supplier.SUPPLIERCITY;
                supplierUpdate.SUPPLIERCOUNTRY = supplier.SUPPLIERCOUNTRY;
                supplierUpdate.SUPPLIERDATELIMIT = supplier.SUPPLIERDATELIMIT;
                supplierUpdate.SUPPLIERMAIL = supplier.SUPPLIERMAIL;
                supplierUpdate.SUPPLIERNAME = supplier.SUPPLIERNAME;
                supplierUpdate.SUPPLIERPASSWORD = supplier.SUPPLIERPASSWORD;
                supplierUpdate.SUPPLIERPHONE = supplier.SUPPLIERPHONE;
                supplierUpdate.SUPPLIERZIP = supplier.SUPPLIERZIP;

                db.getModel().SaveChanges();

                return true;
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);

                return false;
            }
        }

        public bool deleteProduct(int productId)
        {
            try
            {
                PRODUCT product = (PRODUCT)db.check(db.getModel().PRODUCT.
                        First(prod => prod.PRODUCTID == productId));

                db.getModel().DeleteObject(product);
                db.getModel().SaveChanges();

                return true;
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);

                return false;
            }
        }

        public bool addProductInCatalog(int productId, int catalogId)
        {
            try
            {
                PRODUCT product = (PRODUCT)db.check(db.getModel().PRODUCT.
                        First(prod => prod.PRODUCTID == productId));

                CATALOG catalog = (CATALOG)db.check(db.getModel().CATALOG.
                        First(cat => cat.CATALOGID == catalogId));

                product.CATALOG.Add(catalog);
                db.getModel().SaveChanges();

                return true;
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);

                return false;
            }
        }

        public bool removeProductFromCatalog(int productId, int catalogId)
        {
            try
            {
                PRODUCT product = (PRODUCT)db.check(db.getModel().PRODUCT.
                        First(prod => prod.PRODUCTID == productId));

                CATALOG catalog = (CATALOG)db.check(db.getModel().CATALOG.
                        First(cat => cat.CATALOGID == catalogId));

                product.CATALOG.Remove(catalog);
                db.getModel().SaveChanges();

                return true;
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);

                return false;
            }
        }

        public bool deleteCatalog(int catalogId)
        {
            try
            {
                CATALOG catalog = (CATALOG)db.check(db.getModel().CATALOG.
                    First(cata => cata.CATALOGID == catalogId));

                db.getModel().DeleteObject(catalog);
                db.getModel().SaveChanges();

                return true;
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);

                return false;
            }
        }

        public List<SerializedOrderLine> getSupplierOrders(int supplierId)
        {
            try
            {
                var selectOrders = db.check(db.getModel().ORDER.Select(order => order));
                List<SerializedOrderLine> listOrderLines = new List<SerializedOrderLine>();

                foreach (ORDER order in selectOrders)
                {
                    foreach (CONTAIN article in order.CONTAIN)
                    {
                        PRODUCT product = (PRODUCT)db.getModel().PRODUCT.First(prod => prod.PRODUCTID == article.PRODUCTID);

                        if (product.SUPPLIERID == supplierId)
                        {
                            SerializedProduct serializedProduct = Library.getSerializedProduct(product);
                            SerializedOrder serializedOrder = Library.getSerializedOrder(order);

                            CLIENT client = (CLIENT)db.check(db.getModel().CLIENT.
                                First(cli => cli.CLIENTID == serializedOrder.CLIENTID));

                            SerializedClient serializedClient = Library.getSerializedClient(client);

                            listOrderLines.Add(new SerializedOrderLine(
                                serializedOrder,
                                serializedProduct,
                                serializedClient,
                                Library.getSerializedContain(article)));
                        }
                    }
                }

                return listOrderLines;
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                return new List<SerializedOrderLine>();
            }
        }

    }
}